From 9a6be788d95fd9291cb42977aa45968a946e0483 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Tue, 10 Jun 2014 14:59:25 -0700 Subject: [PATCH] Move Manifest parsing into its own module --- src/cargo/core/manifest.rs | 177 +-------------------------- src/cargo/core/mod.rs | 3 +- src/cargo/ops/cargo_read_manifest.rs | 28 ++--- src/cargo/util/mod.rs | 1 + 4 files changed, 13 insertions(+), 196 deletions(-) diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 025e31bcc..31e7b701d 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -1,18 +1,13 @@ use std::fmt; use std::fmt::{Show,Formatter}; -use std::collections::HashMap; use semver::Version; -use serialize::{Encoder,Decoder,Encodable,Decodable}; +use serialize::{Encoder,Decoder,Encodable}; use core::{ Dependency, NameVer, - Package, Summary }; use core::dependency::SerializedDependency; -use util::{CargoResult,Require,toml_error,simple_human}; -use toml; -use toml::{Table, ParseError}; #[deriving(PartialEq,Clone)] pub struct Manifest { @@ -174,15 +169,6 @@ impl Target { } } -/* - * - * ===== Serialized ===== - * - */ - -type TomlLibTarget = TomlTarget; -type TomlBinTarget = TomlTarget; - #[deriving(Decodable,Encodable,PartialEq,Clone,Show)] pub struct Project { pub name: String, @@ -190,168 +176,9 @@ pub struct Project { pub authors: Vec } -/* - * TODO: Make all struct fields private - */ - -#[deriving(Encodable,PartialEq,Clone,Show)] -pub enum TomlDependency { - SimpleDep(String), - DetailedDep(DetailedTomlDependency) -} - -#[deriving(Encodable,PartialEq,Clone,Show)] -pub struct DetailedTomlDependency { - version: String, - other: HashMap -} - -#[deriving(Encodable,PartialEq,Clone)] -pub struct TomlManifest { - project: Box, - lib: Option>, - bin: Option>, - dependencies: Option>, -} - -impl TomlManifest { - pub fn from_toml(root: toml::Value) -> CargoResult { - fn decode>(root: &toml::Value, path: &str) -> Result { - let root = match root.lookup(path) { - Some(val) => val, - None => return Err(toml::ParseError) - }; - toml::from_toml(root.clone()) - } - - let project = try!(decode(&root, "project").map_err(|e| toml_error("ZOMG", e))); - let lib = decode(&root, "lib").ok(); - let bin = decode(&root, "bin").ok(); - - let deps = root.lookup("dependencies"); - - let deps = match deps { - Some(deps) => { - let table = try!(deps.get_table().require(simple_human("dependencies must be a table"))).clone(); - - let mut deps: HashMap = HashMap::new(); - - for (k, v) in table.iter() { - match v { - &toml::String(ref string) => { deps.insert(k.clone(), SimpleDep(string.clone())); }, - &toml::Table(ref table) => { - let mut details = HashMap::::new(); - - for (k, v) in table.iter() { - let v = try!(v.get_str() - .require(simple_human("dependency values must be string"))); - - details.insert(k.clone(), v.clone()); - } - - let version = try!(details.find_equiv(&"version") - .require(simple_human("dependencies must include a version"))).clone(); - - deps.insert(k.clone(), DetailedDep(DetailedTomlDependency { - version: version, - other: details - })); - }, - _ => () - } - } - - Some(deps) - }, - None => None - }; - - Ok(TomlManifest { project: box project, lib: lib, bin: bin, dependencies: deps }) - } - - pub fn to_package(&self, path: &str) -> CargoResult { - // TODO: Convert hte argument to take a Path - let path = Path::new(path); - - // Get targets - let targets = normalize(self.lib.as_ref().map(|l| l.as_slice()), self.bin.as_ref().map(|b| b.as_slice())); - - if targets.is_empty() { - debug!("manifest has no build targets; project={}", self.project); - } - - let mut deps = Vec::new(); - - // Collect the deps - match self.dependencies { - Some(ref dependencies) => { - for (n, v) in dependencies.iter() { - let version = match *v { - SimpleDep(ref string) => string.clone(), - DetailedDep(ref details) => details.version.clone() - }; - - deps.push(try!(Dependency::parse(n.as_slice(), version.as_slice()))) - } - } - None => () - } - - // TODO: https://github.com/mozilla/rust/issues/14049 - let root = Path::new(path.dirname()); - - Ok(Package::new( - &Manifest::new( - &Summary::new(&self.project.to_name_ver(), deps.as_slice()), - targets.as_slice(), - &Path::new("target")), - &root)) - } -} - impl Project { - fn to_name_ver(&self) -> NameVer { + pub fn to_name_ver(&self) -> NameVer { NameVer::new(self.name.as_slice(), self.version.as_slice()) } } -#[deriving(Decodable,Encodable,PartialEq,Clone,Show)] -struct TomlTarget { - name: String, - path: Option -} - -fn normalize(lib: Option<&[TomlLibTarget]>, bin: Option<&[TomlBinTarget]>) -> Vec { - log!(4, "normalizing toml targets; lib={}; bin={}", lib, bin); - - fn lib_targets(dst: &mut Vec, libs: &[TomlLibTarget]) { - let l = &libs[0]; - let path = l.path.clone().unwrap_or_else(|| format!("src/{}.rs", l.name)); - dst.push(Target::lib_target(l.name.as_slice(), &Path::new(path))); - } - - fn bin_targets(dst: &mut Vec, bins: &[TomlBinTarget], default: |&TomlBinTarget| -> String) { - for bin in bins.iter() { - let path = bin.path.clone().unwrap_or_else(|| default(bin)); - dst.push(Target::bin_target(bin.name.as_slice(), &Path::new(path))); - } - } - - let mut ret = Vec::new(); - - match (lib, bin) { - (Some(ref libs), Some(ref bins)) => { - lib_targets(&mut ret, libs.as_slice()); - bin_targets(&mut ret, bins.as_slice(), |bin| format!("src/bin/{}.rs", bin.name)); - }, - (Some(ref libs), None) => { - lib_targets(&mut ret, libs.as_slice()); - }, - (None, Some(ref bins)) => { - bin_targets(&mut ret, bins.as_slice(), |bin| format!("src/{}.rs", bin.name)); - }, - (None, None) => () - } - - ret -} diff --git a/src/cargo/core/mod.rs b/src/cargo/core/mod.rs index d9bb6d504..652d66da7 100644 --- a/src/cargo/core/mod.rs +++ b/src/cargo/core/mod.rs @@ -9,7 +9,8 @@ pub use self::registry::{ pub use self::manifest::{ Manifest, Target, - TargetKind + TargetKind, + Project }; pub use self::package::{ diff --git a/src/cargo/ops/cargo_read_manifest.rs b/src/cargo/ops/cargo_read_manifest.rs index a4b197aaa..fb71c9a0c 100644 --- a/src/cargo/ops/cargo_read_manifest.rs +++ b/src/cargo/ops/cargo_read_manifest.rs @@ -1,28 +1,16 @@ use toml; -use toml::from_toml; use core::Package; -use core::manifest::{TomlManifest}; -use util::{toml_error,human_error,CargoResult,CargoError}; +use util::toml::toml_to_package; +use util::{CargoResult,human_error,toml_error}; pub fn read_manifest(path: &str) -> CargoResult { - let root = try!(parse_from_file(path).map_err(|err: CargoError| - human_error("Cargo.toml is not valid Toml".to_str(), format!("path={}", path), err))); - - let toml = try!(load_toml(root).map_err(|err: CargoError| - human_error("Cargo.toml is not a valid Cargo manifest".to_str(), format!("path={}", path), err))); - - toml.to_package(path) + let root = try!(parse_from_file(path)); + toml_to_package(root, &Path::new(path)) } fn parse_from_file(path: &str) -> CargoResult { - toml::parse_from_file(path.clone()).map_err(to_cargo_err) -} - -fn load_toml(root: toml::Value) -> CargoResult { - TomlManifest::from_toml(root) -} - -fn to_cargo_err(err: toml::Error) -> CargoError { - debug!("toml; err={}", err); - toml_error("Problem loading manifest", err) + toml::parse_from_file(path.clone()).map_err(|err| { + let err = toml_error("Couldn't parse Toml", err); + human_error("Cargo.toml is not valid Toml".to_str(), format!("path={}", path), err) + }) } diff --git a/src/cargo/util/mod.rs b/src/cargo/util/mod.rs index 98d127efe..2d2229c3c 100644 --- a/src/cargo/util/mod.rs +++ b/src/cargo/util/mod.rs @@ -6,3 +6,4 @@ pub mod process_builder; pub mod config; pub mod important_paths; pub mod result; +pub mod toml; -- 2.30.2